package com.ytjj.qmyx.admin.controller.supplyChain;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.fastjson.JSONObject;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.utils.HttpClientUtil;
import com.ytjj.qmyx.admin.annotation.oplog.OperationProductLogger;
import com.ytjj.qmyx.admin.annotation.oplog.annotation.OperationProductLog;
import com.ytjj.qmyx.admin.config.SupplyApiConfig;
import com.ytjj.qmyx.admin.constants.SysLogConstants;
import com.ytjj.qmyx.admin.model.request.ReconciliationOtherMoneyRequest;
import com.ytjj.qmyx.admin.model.request.ReconciliationRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 财务管理
 * <p>
 * 财务对账
 */
@Slf4j
@RestController
@RequestMapping("/reconciliation")
public class ReconciliationController {
    @Autowired
    private SupplyApiConfig supplyApiConfig;

    //账单模板路径
    @Value("${reconciliation.template.path:}")
    private String reconciliationTemplatePath;


    /**
     * 根据条件获取账单
     */
    @PostMapping("/getReconciliationList")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_SELECT, desc = "财务对账列表")
    public String getReconciliationList(@RequestBody ReconciliationRequest request) {
        String s = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/reconciliation/getReconciliationList",
                JSONObject.toJSONString(request), supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 根据账单id查该账单的订单信息
     */
    @GetMapping("/getReconciliationOrders")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_SELECT, desc = "根据账单id查该账单的订单信息")
    public String getReconciliationOrders(@RequestParam Integer id,
                                                @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        Map<String,String> map = new HashMap<>();
        map.put("id",id.toString());
        map.put("pageNum",pageNum.toString());
        map.put("pageSize",pageSize.toString());
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/reconciliation/getReconciliationOrders", map, supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 根据账单id查该账单的订单信息
     */
    @GetMapping("/getReconciliationReturn")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_SELECT, desc = "根据账单id查该账单的退款订单信息")
    public String getReconciliationReturn(@RequestParam Integer id,
                                                @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        Map<String,String> map = new HashMap<>();
        map.put("id",id.toString());
        map.put("pageNum",pageNum.toString());
        map.put("pageSize",pageSize.toString());
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/reconciliation/getReconciliationReturn", map, supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 审核
     */
    @GetMapping("/audit")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_UPDATE, desc = "审核")
    public String audit(@RequestParam Integer id,@RequestParam String auditType,@RequestParam(required = false) String failRemark){
        Map<String, Object> param = new HashMap();
        param.put("id", id);
        param.put("auditType", auditType);
        param.put("failRemark", failRemark);
        OperationProductLogger.log(param);

        Map<String,String> map = new HashMap<>();
        map.put("id",id.toString());
        map.put("auditType",auditType);
        map.put("failRemark",failRemark);
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/reconciliation/audit", map, supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 上传凭证
     */
    @GetMapping("/uploadVoucher")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_UPDATE, desc = "上传凭证")
    public String uploadVoucher(@RequestParam Integer id,@RequestParam String voucherImg){
        Map<String, Object> param = new HashMap();
        param.put("id", id);
        param.put("voucherImg", voucherImg);
        OperationProductLogger.log(param);

        Map<String,String> map = new HashMap<>();
        map.put("id",id.toString());
        map.put("voucherImg",voucherImg);
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/reconciliation/uploadVoucher", map, supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 账单(其他金额)下载模板
     * @param response
     */
    @GetMapping("/downloadTemplate")
    public void download(HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
            File file = new File(reconciliationTemplatePath);
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(reconciliationTemplatePath));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            response.reset();
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(),"utf-8"));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 账单上传其他金额表格文件
     * @param file
     */
    @PostMapping("/uploadFile")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_UPDATE, desc = "账单上传其他金额表格文件")
    public String uploadFile(MultipartFile file, Integer reconciliationId) throws IOException {
        // 导入订单
        if (null == file){
            throw new ApiException("请上传文件");
        }
        Sheet sheet = new Sheet(1, 1, ReconciliationOtherMoneyRequest.class);
        SimpleDateFormat sdfs = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = sdfs.format(new Date());
        String fileName = "平台" + format;
        List<Object> list = new ArrayList<>();
        try {
            list = EasyExcelFactory.read(new BufferedInputStream(file.getInputStream()), sheet);
        } catch (Exception e) {
            throw new ApiException("请导入正确的格式");
        }
        log.info("表格数据：{}", JSONObject.toJSONString(list));
        if (list.size() == 0){
            throw new ApiException("请导入正确的格式");
        }
        List<ReconciliationOtherMoneyRequest> collect = list.stream()
                .map(item -> (ReconciliationOtherMoneyRequest) item)
                .collect(Collectors.toList());
        List<String> childOrderNoList = collect.stream().filter(item -> StringUtils.isNotBlank(item.getChildOrderNo())).map(ReconciliationOtherMoneyRequest::getChildOrderNo).collect(Collectors.toList());
        if (childOrderNoList.size() < collect.size()){
            throw new ApiException("每条数据的订单号不能为空");
        }
        List<ReconciliationOtherMoneyRequest> collect1 = collect.stream().map(item -> {
            item.setFileName(fileName);
            item.setReconciliationId(reconciliationId);
            return item;
        }).collect(Collectors.toList());
        String s = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/reconciliation/uploadFile",
                JSONObject.toJSONString(collect1), supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 获取账单上传的文件
     */
    @GetMapping("/getFileName")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_SELECT, desc = "获取账单上传的文件")
    public String getFileName(@RequestParam Integer reconciliationId){
        Map<String,String> map = new HashMap<>();
        map.put("reconciliationId",reconciliationId.toString());
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/reconciliation/getFileName", map, supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 获取上传文件的数据
     * @param reconciliationId
     * @param source
     * @return
     */
    @GetMapping("/getOtherMoneyDate")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_SELECT, desc = "获取上传文件的数据")
    public String getOtherMoneyDate(@RequestParam Integer reconciliationId, @RequestParam String source) {
        Map<String,String> map = new HashMap<>();
        map.put("reconciliationId",reconciliationId.toString());
        map.put("source",source);
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/reconciliation/getOtherMoneyDate", map, supplyApiConfig.getHeadsMap());
        return s;
    }

    /**
     * 下载账单
     */
    @GetMapping("/downloadReconciliation")
    @OperationProductLog(optModule = SysLogConstants.FINANCE, optType = SysLogConstants.OPERATION_SELECT, desc = "下载账单")
    public String downloadReconciliation(@RequestParam Integer reconciliationId){
        Map<String, Object> param = new HashMap();
        param.put("reconciliationId", reconciliationId);
        OperationProductLogger.log(param);

        Map<String,String> map = new HashMap<>();
        map.put("reconciliationId",reconciliationId.toString());
        String s = HttpClientUtil.doGet(supplyApiConfig.getUrl() + "/reconciliation/downloadReconciliation", map, supplyApiConfig.getHeadsMap());
        return s;
    }
}
